package com.linshengjian.snowball.guard.filter;

import com.linshengjian.snowball.guard.GuardProperties;
import com.linshengjian.snowball.guard.service.GuardUserService;
import com.linshengjian.snowball.guard.utils.TokenUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 每次访问时，从header中获取token信息并解析有消息
 */

public class TokenAuthenticationFilter extends OncePerRequestFilter{

    private GuardUserService service;
    private GuardProperties properties;


    public TokenAuthenticationFilter( GuardProperties properties, GuardUserService service) {
        this.service = service;
        this.properties = properties;
    }


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        // 获取header中的token
        String tokenStr = request.getHeader(this.properties.getToken().getHeader());

        if (tokenStr != null && tokenStr.startsWith(this.properties.getToken().getTokenHead())) { // 比对token开头是否是规定字符
            final String authToken = tokenStr.substring(this.properties.getToken().getTokenHead().length()); // The part after "Bearer "

            TokenUtils utils = new TokenUtils(properties);

            if (utils.setToken(authToken) && utils.isValid()) {

                UserDetails user = service.findByUserName(utils.getUserName());
                if (user != null) {
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }

                if ((utils.getExpiration().getTime() - System.currentTimeMillis()) / 1000 < properties.getToken().getExpiration() / 3) {
                    // 如果token的失效时间小于 3分一的有效时间，刷新 token
                    response.setHeader(properties.getToken().getHeader(), properties.getToken().getTokenHead() + utils.refresh());
                }
            }
        }

        chain.doFilter(request, response);
    }
}